package com.java8.lockTest.test4;

/**
 * <p>Description: [乐观锁]</p>
 * Created on 2020/5/26
 *
 * @author <a href="mailto: 819712047@qq.com">谢振东 </a>
 * @version 1.0
 */
public class OptimisticLock {
    public static int value = 0; // 多线程同时调用的操作对象

    /**
     * A线程要执行的方法
     */
    public static void invoke(int Avalue, String i)
            throws InterruptedException {
        //延长执行时间
        Thread.sleep(1000L);
        //判断value版本
        if (Avalue != value) {
            System.out.println(Avalue + ":" + value + "A版本不一致,不执行");
            value--;
        } else {
            //对数据操作
            Avalue++;
            value = Avalue;
            //对数据操作
            System.out.println(i + ":" + value);
        }
    }

    /**
     * B线程要执行的方法
     */
    public static void invoke2(int Bvalue, String i)
            throws InterruptedException {
        //延长执行时间
        Thread.sleep(1000L);
        //判断value版本
        if (Bvalue != value) {
            System.out.println(Bvalue + ":" + value + "B版本不一致,不执行");
        } else {
            System.out.println("B:利用value运算,value=" + Bvalue);
        }
    }

    /**
     * 测试,期待结果:B线程执行的时候value数据总是当前最新的
     */
    public static void main(String[] args) throws InterruptedException {
        //A线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 3; i++) {
                        //A获取的value
                        int Avalue = OptimisticLock.value;
                        OptimisticLock.invoke(Avalue, "A");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //B线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 0; i < 3; i++) {
                        //B获取的value
                        int Bvalue = OptimisticLock.value;
                        OptimisticLock.invoke2(Bvalue, "B");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
